package pl.iachoo.ctl.tabory.dao.hibernate.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import pl.iachoo.ctl.tabory.dao.api.services.IVagonService;
import pl.iachoo.ctl.tabory.dao.data.vo.CompositionVO;
import pl.iachoo.ctl.tabory.dao.data.vo.VagonVO;
import pl.iachoo.ctl.tabory.dao.hibernate.services.BaseDaoService;

public class VagonDaoServiceImpl extends BaseDaoService<VagonVO> implements
		IVagonService {

	private final Logger logger = Logger.getLogger(VagonDaoServiceImpl.class);

	public VagonDaoServiceImpl(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	@Override
	public void deleteVagon(VagonVO vagon) throws Exception {
		logger.debug("Deleting: " + vagon);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			VagonVO tmpVagon = (VagonVO) session.get(VagonVO.class,
					vagon.getId());
			session.delete(tmpVagon);
			transaction.commit();
			logger.debug("Delete OK.");
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<VagonVO> getListAllVagons() throws Exception {
		logger.debug("Getting all Vagons.");
		Transaction transaction = null;
		Session session = null;
		List<VagonVO> listVagons = new ArrayList<VagonVO>();
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			listVagons = session.createCriteria(VagonVO.class).list();
			transaction.commit();
			logger.debug(listVagons);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return listVagons;
	}

	@Override
	public VagonVO getVagon(Long vagonId) throws Exception {
		logger.debug("Getting Vagon for Id: " + vagonId);
		Transaction transaction = null;
		Session session = null;
		VagonVO vagon = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(VagonVO.class);
			criteria.add(Restrictions.eq("id", vagonId));
			vagon = (VagonVO) criteria.uniqueResult();
			transaction.commit();
			logger.debug(vagon);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return vagon;
	}

	@Override
	public List<VagonVO> getVagons(CompositionVO composition) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public VagonVO saveUpdateVagon(VagonVO vagon) throws Exception {
		logger.debug("Saving/updating Vagon: " + vagon);
		if (vagon.getId() == null) {
			saveVagon(vagon);
		} else {
			updateVagon(vagon);
		}
		return vagon;
	}

	public List<VagonVO> updateList(List<VagonVO> listVagons) throws Exception {
		logger.debug("Updating vagon list: " + listVagons);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			for (VagonVO vagon : listVagons) {
				session.update(vagon);
			}
			transaction.commit();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
		return listVagons;
	}

	private void saveVagon(VagonVO vagon) throws Exception {
		logger.debug("Saving Vagon: " + vagon);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.save(vagon);
			transaction.commit();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
	}

	private void updateVagon(VagonVO vagon) throws Exception {
		logger.debug("Updating Vagon: " + vagon);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.update(vagon);
			transaction.commit();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			transaction.rollback();
			throw e;
		} finally {
			session.close();
		}
	}

}
